import axios,{type Method} from 'axios'
// 导入仓库 token从这里来
import {useUserStore} from '@/stores'
import { showToast } from 'vant'
import router from '@/router'
// 产生axios实例
const instance = axios.create({
  // TODO 1. 基础地址，超时时间
  baseURL:'https://consult-api.itheima.net/',
//   设置超时时间为10s
  timeout:1000
})

// 请求拦截器
instance.interceptors.request.use(
  (config) => {
    // TODO 2. 携带token
    
    const store= useUserStore()
    if(store.user?.token && config.headers){
        config.headers['Authorization']='Bearer '+store.user.token
    }

    return config
  },
  (err) => Promise.reject(err)
)

// 响应拦截器
instance.interceptors.response.use(
  (res) => {
    // TODO 3. 处理业务失败
    if(res.data?.code!=10000){
        showToast(res.data.message || '业务失败')
    }
    // TODO 4. 摘取核心响应数据
    return res.data
  },
  (err) => {
    // TODO 5. 处理401错误
    if(err.response.status==401){
        // 如果访问一个无法找到的页面，就要跳到登录页面重新登陆,并且删除本地信息
        const store = useUserStore()
        // 删除本地信息
        store.delUser()

        // 跳转到登录页面
        router.push({
            path:'/login',
            query:{returl:router.currentRoute.value.fullPath}
    
    })
    }
    
    return Promise.reject(err)
  }
)

export default instance
// 加上泛型
// 这个需要替换axsio.request默认的响应成功后的结果类型
// 之前是：传 { name: string } 然后res是   res = { data: { name: string } }
// 但现在：在响应拦截器中返回了 res.data  也就是将来响应成功后的结果，和上面的类型一致吗？
// 所以要：request<数据类型，数据类型>() 这样才指定了 res.data 的类型
// 但是呢：后台返回的数据结构相同，所以可以抽取相同的类型
type Data<T> = {
    code: number
    message: string
    data: T
  }
  // 4. 请求工具函数
 export const request = <T>(url: string, method: Method = 'get', submitData?: object) => {
    // 在上面导入一个 Method: {type Method}
    return instance.request<T, Data<T>>({
      url,
      method,
      [method.toLowerCase() === 'get' ? 'params' : 'data']: submitData
    })
  }